#include<iostream>
#include<fstream>
#include<string>
#include<cstdlib>
#include<unistd.h>
#include<cstring>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/socket.h>
#define PAGE "index.html"
using namespace std;
int main()
{
  int listen_sock=socket(AF_INET,SOCK_STREAM,0);
  if(listen_sock<0)
  {
    cout<<"socket error"<<endl;
    return 1;
  }
  struct sockaddr_in local;
  memset(&local,0,sizeof(local));
  local.sin_family=AF_INET;
  local.sin_addr.s_addr=INADDR_ANY;
  local.sin_port=htons(8081);
  if(bind(listen_sock,(struct sockaddr*)&local,sizeof(local))<0)
  {
    cout<<"bind error"<<endl;
    return 2;
  }
  if(listen(listen_sock,5)<0)
  {
    std::cout<<"listen error"<<endl;
    return 3;
  }
  struct sockaddr_in peer;
  for(;;)
  {
    socklen_t len=sizeof(peer);
    int sock=accept(listen_sock,(struct sockaddr*)&peer,&len);
    if(sock<0)
    {
      cout<<"accept error"<<endl;
      continue;
    }
    if(fork()==0)
    {
      if(fork()>0)
      {
        exit(0);
      }
      close(listen_sock);
      char buffer[1024];
      recv(sock,buffer,sizeof(buffer),0);
      cout<<"################http request begin ###################"<<endl;
      cout<<buffer<<endl;
      cout<<"################http request end   ###################"<<endl;
      ifstream in(PAGE);
      if(in.is_open())
      {
        in.seekg(0,ios::end);
        size_t len=in.tellg();
        in.seekg(0,ios::beg);
        char* file=new char[len];
        in.read(file,len);
        in.close();
        
        string status_line="http/1.0 200 OK\n";
        string response_header="Content-Length:"+to_string(len)+"\n";
        string blank="\n";
        string all=status_line+response_header+blank;
        send(sock,all.c_str(),all.size(),0);
        send(sock,file,len,0);         

        delete[] file;
      }
      close(sock);
      exit(0);
    }
    close(sock);
    waitpid(-1,nullptr,0);
  }
  
  return 0;
}
